 
  /*
                         \\\|///  
                       \\  - -  //  
                        (  @ @  )  
+---------------------oOOo-(_)-oOOo-------------------------+  
|                                                           |  
|                                                           |   
|                                                           |  
|                                                           |   
|                                                           |  
|                                                           |   
|                                                           |  
|                                                           |  
|                            Oooo            www.the0.net   |  
+----------------------oooO--(   )--------------------------+  
                      (   )   ) /  
                       \ (   (_/  
                        \_)      

*/

#include "rtc.h"
 #include "irq.h"
#include <nxp/iolpc2378.h>  
//#include "LPC23xx.h"				/* LPC23xx/24xx definitions */
#include "type.h"
#include "uart.h"
#include "i2c.h"
#include "modem.h"

 #include "FreeRTOS.h"
 #include "semphr.h"



#pragma location = "EMAC_DMA_RAM"
datetime_t rtnow; 
#pragma location = "EMAC_DMA_RAM"
int rsp_hour=0;
#pragma location = "EMAC_DMA_RAM"
int rsp_min=0;
#pragma location = "EMAC_DMA_RAM"
int rsp_sec=0;


extern xSemaphoreHandle xSemUPnow, xSemSPnow;

extern int R_UP, SPinUP;

int rup_hour=0;
int rup_min=0;
int rup_sec=0;
extern int start_init;
//#pragma location = "EMAC_DMA_RAM"
//static int init[RTC_ALARMS_COUNT] = {-1, -1, -1, -1, -1, -1};
//#pragma location = "EMAC_DMA_RAM"
//static int counters[RTC_ALARMS_COUNT] = {-1, -1, -1, -1, -1, -1};
#pragma location = "EMAC_DMA_RAM"
static int alarms[RTC_ALARMS_COUNT] = {1, 1, 1, 1, 1, 1};
extern int TCSP;
extern int R_SP;
extern int count_up;
extern int GSM_READYF;
extern int TC_UP;
extern int trans_r;
char *rtc_s;
int rtc_i;
int tpx;
int ret;


void SET_TSPX(int TSP)
{ 
  for(int i=1;i<255;i++)
  {
      TCSP=R_SP-TCUP;    
      if (TCSP<TCUP){count_up=i;R_SP=TCSP;i=255;}
  }
  count_up=count_up+1;
}

void SET_TSUP(int TSP)
{ 
  int i=0;
  for(i=0;i<2000;i++)
  {
      if (TSP<60)
      {
        TCUP=TSP;
        TCUMN=i;
        i=2000;    
      }
    TSP=TSP-60;
  }
 //TCUP=TSP;  
}

int TIME_CONTROL(int TCN_WS)
{
RtcGetTime(&rtnow);
int itrc=rtnow.second;
int itrm=rtnow.minute;
int itrh=rtnow.hour;
itrc=itrc+TCUP;
if (itrc >= 60)
{
itrc -= 60;
itrm=itrm+1;
} 

rtnow.second=itrc;
itrm=itrm+TCUMN;

if (itrm >= 60)
{
itrm -= 60;
itrh=itrh+1;
} 
rtnow.minute=itrm;

if (itrh >= 60)
{
itrh -= 60;
}  
rtnow.hour=itrh;

  
  switch (TCN_WS)						//Read result code and switch to next action
{ 
case 1:  

     
TC_UP=1;
/**/
   if (rtnow.hour!=rup_hour)
     { 
      rup_hour=rtnow.hour;
      rsp_hour=rtnow.hour;
      START_INIT_UP_SP();
      start_init=1;  
      CIIR = 0x00; //disable counter ints   
        return 7;    
     }  

         if (rtnow.minute>rsp_min)
          { 
            ALSEC=rsp_sec;
            ALMIN=rsp_min;
            rup_hour=rtnow.hour;
            rup_sec=rtnow.second;
            rup_min=rtnow.minute;
            CIIR = 0x00; //disable counter ints  
            return 8;
          }




      if (rtnow.second>rsp_sec)
      {
         if (rtnow.minute>=rsp_min)
          { 
            ALSEC=rsp_sec;
            ALMIN=rsp_min;
            rup_hour=rtnow.hour;
            rup_sec=rtnow.second;
            rup_min=rtnow.minute;
            CIIR = 0x00; //disable counter ints  
            return 8;
          }
        
      }
      
      
      
         if (rtnow.minute>rsp_min)
          { 
            ALSEC=rsp_sec;
            ALMIN=rsp_min;
            rup_hour=rtnow.hour;
            rup_sec=rtnow.second;
            rup_min=rtnow.minute;
            CIIR = 0x00; //disable counter ints  
            return 8;
          }
        
       if (rtnow.minute==rsp_min)
        { 
          if (rtnow.second==rsp_sec)
            {
                  ALSEC=rsp_sec;
                  ALMIN=rsp_min;
                  CIIR = 0x00; //disable counter ints  
                 
                  return 7;
            }
        }

   ALSEC=itrc;
   ALMIN=itrm;
   
   CIIR = 0x00; //disable counter ints   
break; 

case 2:  
  
  
if (rtnow.hour!=rsp_hour)
     { 
      rup_hour=rtnow.hour;
      rsp_hour=rtnow.hour;
      START_INIT_UP_SP();
      start_init=1;  
      CIIR = 0x00; //disable counter ints         
                  return 7;    
     } 
  
  if (trans_r!=3)
  {
trans_r=1; 
  }
if (GSM_READYF!=0)
   {    
     GSM_READYF=1;
   }
rsp_hour=rtnow.hour;
rsp_min=rtnow.minute;
rsp_sec=rtnow.second;
break; 

case 3:
 if (rtnow.hour!=rsp_hour)
     { 
      rup_hour=rtnow.hour;
      rsp_hour=rtnow.hour;
      START_INIT_UP_SP();
      start_init=1;  
      CIIR = 0x00; //disable counter ints   
       return 7;    
     }  
    if (trans_r!=3)
  {
  trans_r=1;
  }
if (GSM_READYF!=0)
   {    
     GSM_READYF=1;  //SP*
   } 
rsp_hour=rtnow.hour; 
rsp_min=rtnow.minute;
rsp_sec=rtnow.second; 
ALSEC=rup_sec;
ALMIN=rup_min;
CIIR = 0x00; //disable counter ints  
return 2;
break;   
  
default:
break;  
}

return 1;

  
}


#define AllAlarmDis     0xFF

void SetUpRTCAlarm(int period)
{ datetime_t  AlarmTime;
//  
  RtcGetTime(&AlarmTime);
  AMR = AllAlarmDis;
//seconds:
  AlarmTime.second += period%60;  period/=60;
  if(AlarmTime.second>59) {AlarmTime.second-=60; ++AlarmTime.minute;}
  ALSEC = AlarmTime.second;   AMR_bit.AMRSEC=0;
//minutes:
  if(period)
   {
     AlarmTime.minute += period%60;  period/=60;
     if(AlarmTime.minute>59) {AlarmTime.minute-=60; ++AlarmTime.hour;}
     ALMIN = AlarmTime.minute;   AMR_bit.AMRMIN=0;
    }
//hours:
  if(period)
   {
     AlarmTime.hour += period%24;  period/=24;
     if(AlarmTime.hour>23) {AlarmTime.hour-=24; ++AlarmTime.day;}
     ALHOUR = AlarmTime.hour;   AMR_bit.AMRHOUR=0;
    }
//
 CIIR = 0x00; //disable counter ints 
}








void SET_TCN(void)
{

RtcGetTime(&rtnow);
int itrc=rtnow.second;
int itrm=rtnow.minute;

itrc=itrc+TCUP;
if (itrc >= 60)
{
itrc -= 60;
itrm=itrm+1;
} 
ALSEC=itrc;

itrm=itrm+TCUMN;

if (itrm >= 60)
{
itrm -= 60;
} 
/**/
ALMIN=itrm;
 CIIR = 0x00; //disable counter ints 
 
}

__irq void RTCHandler(void) 
{ 
  static int cyclesUP=0;  /*static*/ portBASE_TYPE xHiPriorTaskWoken;
  
  if(ILR_bit.RTCALF) 
   { 
     SetUpRTCAlarm(R_UP);
     if(xSemaphoreGiveFromISR(xSemUPnow, &xHiPriorTaskWoken)==pdFAIL) cyclesUP=0;
     if( ++cyclesUP >= SPinUP )
       {cyclesUP=0; xSemaphoreGiveFromISR(xSemSPnow, &xHiPriorTaskWoken);}
    }

/////////////////  
//SET_diXR(); 
////////////////
  
  ILR = ILR;     VICADDRESS = 0;	/* Acknowledge Interrupt */
}

void rtc_enable()
{
  PCONP |= 0x200; //Enable power for RTC
  if(!CCR_bit.CLKSRC) {CCR_bit.CLKEN=0; CCR_bit.CLKSRC=1;}
  if(!CCR_bit.CLKEN)   CCR_bit.CLKEN=1;
  ILR = ILR;     //Clear RTC interrupt register
  CIIR = 0x00;    //Enable only second count interrupt. One second interrupt.
  CISS = 0;       //Disable all subsecond interrupts.
  SetUpRTCAlarm(R_UP);
//
  if ( install_irq( RTC_INT, (void *)RTCHandler, HIGHEST_PRIORITY ) == FALSE )
    { while ( 1 );/* very bad happened */ }
}

void rtc_set_time(datetime_t time)
{
  CCR_bit.CLKEN = 0;
    SEC = time.second;
    MIN = time.minute; //  Minute value [0-59]
    HOUR = time.hour; //  Hour value [0-23]
    DOM = time.day; //  Day of month value [1-31]
    MONTH = time.month; //  Month value [1-12]
    YEAR = time.year; //  Year value
  CCR_bit.CLKEN = 1;
  SetUpRTCAlarm(R_UP);  

}
/*
datetime_t rtc_get_time(void)
{
  datetime_t time;
  time.second = ((CTIME0 & 0x0000003F)>>0);
  time.minute = ((CTIME0 & 0x00003F00)>>8);
  time.hour = ((CTIME0 & 0x001F0000)>>16);
  time.day = ((CTIME1 & 0x0000001F)>>0);
  time.month = ((CTIME1 & 0x0000FF00)>>8);
  time.year = ((CTIME1 & 0x0FFF0000)>>16);
  CCR |= 0x01;

  return (time);
}
*/

void    RtcGetTime(datetime_t *time){
  time->second = ((CTIME0 & 0x0000003F)>>0);
  time->minute = ((CTIME0 & 0x00003F00)>>8);
  time->hour = ((CTIME0 & 0x001F0000)>>16);
  time->day = ((CTIME1 & 0x0000001F)>>0);
  time->month = ((CTIME1 & 0x0000FF00)>>8);
  time->year = ((CTIME1 & 0x0FFF0000)>>16);
  CCR |= 0x01;
}



void RTCGetTime( RTCTime* LocalTime ) 
{
	if ( LocalTime == NULL ) return;

	LocalTime->RTC_Sec  = SEC;
	LocalTime->RTC_Min  = MIN;
	LocalTime->RTC_Hour = HOUR;
	LocalTime->RTC_Mday = DOM;
	LocalTime->RTC_Wday = DOW;
	LocalTime->RTC_Yday = DOY;
	LocalTime->RTC_Mon  = MONTH;
	LocalTime->RTC_Year = YEAR;
	return;
}


void rtc_alarm_set(unsigned int id, int period)
{
  assert(id < RTC_ALARMS_COUNT);
  //init[id] = period;
  //counters[id] = 0;
}

bool rtc_alarm_get(unsigned int id)
{
  assert(id < RTC_ALARMS_COUNT);
 ret = alarms[id];
  alarms[id] = 0;
  return ret > 0;
}

DWORD get_fattime (void); /* avoid warning */
DWORD get_fattime (void)
{
	RTCTime t;
	DWORD res;

	RTCGetTime( &t );
	res = (
		(( t.RTC_Sec/2 )       << 0UL  ) |
		(( t.RTC_Min )         << 5UL  ) |
		(( t.RTC_Hour )        << 11UL ) |
		(( t.RTC_Mday )        << 16UL ) |
		(( t.RTC_Mon )         << 21UL ) |
		(( t.RTC_Year-1980 )   << 25UL )
	);

	return res;
}

